#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include "TcpServer.hpp"
#include "Calculator.hpp"
#include "Protocol.hpp"

using namespace My_Log;

using cal_t = std::function<Response(const Request &req)>;

class Prase
{
public:
    Prase(cal_t cal) : _cal(cal) {}
    std::string Entry(std::string &package)
    {
        std::string messag;
        std::string resstr;
        // 解码 len\r\n{json}\r\n
        while (Decode(package, &messag))
        {
            // 判空
            if (messag.empty())
                break;

            // 反序列化
            Request req;
            if (!req.Deserialize(messag))
                break;

            // 计算
            Response res = _cal(req);

            // 序列化
            std::string tmp;
            res.Serialize(tmp);

            // 编码
            if (!Encode(tmp))
                break;

            resstr += tmp;
        }
        return resstr;
    }
    ~Prase() {}

private:
    cal_t _cal;
};

int main()
{

    Calculator cal;

    Prase pra([&cal](const Request &req)
              { return cal.Execute(req); });

    std::unique_ptr<TcpServer> ser_ptr = std::make_unique<TcpServer>([&pra](std::string &package)
                                                                     { return pra.Entry(package); });

    ser_ptr->InitServer();
    ser_ptr->Start();
    ser_ptr->~TcpServer();

    return 0;
}